home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GDEVMSWN.C < prev    next >
C/C++ Source or Header  |  1993-05-12  |  22KB  |  746 lines

  1. /* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* gdevmswn.c */
  20. /*
  21.  * Microsoft Windows 3.n driver for Ghostscript.
  22.  * Original version by Russell Lang and Maurice Castro with help from
  23.  * Programming Windows, 2nd Ed., Charles Petzold, Microsoft Press;
  24.  * created from gdevbgi.c and gnuplot/term/win.trm 5th June 1992.
  25.  * Extensively modified by L. Peter Deutsch, Aladdin Enterprises.
  26.  */
  27. #include "gdevmswn.h"
  28. #include "gp.h"
  29. #include "gpcheck.h"
  30. #include "gsprops.h"
  31. #include "gdevpccm.h"
  32.  
  33. /* Forward references */
  34. private void near win_makeimg(P1(gx_device_win *));
  35. LRESULT CALLBACK _export WndImgProc(HWND, UINT, WPARAM, LPARAM);
  36. LRESULT CALLBACK _export WndImgChildProc(HWND, UINT, WPARAM, LPARAM);
  37.  
  38. /* Define the repaint interval in milliseconds. */
  39. /* Suggested values: 10000 for 286, 5000 for 386, 3000 for 486. */
  40. #define repaint_interval 5000
  41. #define TIMER_ID 1
  42.  
  43. /* Open the win driver */
  44. int
  45. win_open(gx_device *dev)
  46. {    HDC hdc;
  47.     int depth;
  48.     WNDCLASS wndclass;
  49.     static BOOL registered = FALSE;
  50.  
  51.     /* Initialize the scrolling information. */
  52.     
  53.     wdev->cxClient = wdev->cyClient = 0;
  54.     wdev->nVscrollPos = wdev->nVscrollMax = 0;
  55.     wdev->nHscrollPos = wdev->nHscrollMax = 0;
  56.  
  57.     wdev->update = wdev->timer = FALSE;
  58.  
  59.     if (dev->width == INITIAL_WIDTH)
  60.       dev->width  = (int)(8.5  * dev->x_pixels_per_inch);
  61.     if (dev->height == INITIAL_HEIGHT)
  62.       dev->height = (int)(11.0 * dev->y_pixels_per_inch);
  63.  
  64.     /* If this is the first instance, register the window classes. */
  65.     if (!registered) {
  66.         /* register the window class for graphics */
  67.         wndclass.style = CS_HREDRAW | CS_VREDRAW;
  68.         wndclass.lpfnWndProc = WndImgChildProc;
  69.         wndclass.cbClsExtra = 0;
  70.         wndclass.cbWndExtra = sizeof(LONG);
  71.         wndclass.hInstance = phInstance;
  72.         wndclass.hIcon = LoadIcon(phInstance,"grpicon");
  73.         wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  74.         wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  75.         wndclass.lpszMenuName = NULL;
  76.         wndclass.lpszClassName = szAppName;
  77.         RegisterClass(&wndclass);
  78.  
  79.         wndclass.style = CS_HREDRAW | CS_VREDRAW;
  80.         wndclass.lpfnWndProc = WndImgProc;
  81.         wndclass.cbClsExtra = 0;
  82.         wndclass.cbWndExtra = sizeof(LONG);
  83.         wndclass.hInstance = phInstance;
  84.         wndclass.hIcon = LoadIcon(phInstance,"grpicon");
  85.         wndclass.hCursor = LoadCursor((HINSTANCE)NULL, IDC_ARROW);
  86.         wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
  87.         wndclass.lpszMenuName = NULL;
  88.         wndclass.lpszClassName = szImgName;
  89.         RegisterClass(&wndclass);
  90.     
  91.         registered = TRUE;
  92.     }
  93.  
  94.     win_makeimg(wdev);
  95.     wdev->hdctext = NULL;
  96.  
  97.     /* Set parameters that were unknown before opening device */
  98.     /* Find out if the device supports color */
  99.     /* We recognize 2, 16 or 256 color devices */
  100.     hdc = GetDC(wdev->hwndimgchild);
  101.     depth = GetDeviceCaps(hdc,PLANES) * GetDeviceCaps(hdc,BITSPIXEL);
  102.     ReleaseDC(wdev->hwndimgchild,hdc);
  103.     if ( depth >= 8 ) { /* use 64 static colors and 166 dynamic colors from 8 planes */
  104.         static const gx_device_color_info win_256color = dci_color(8,31,4);
  105.         dev->color_info = win_256color;
  106.         wdev->nColors = 64;
  107.     }
  108.     else if ( depth >= 4 ) {
  109.         static const gx_device_color_info win_16ega_color = dci_ega;
  110.         static const gx_device_color_info win_16vga_color = dci_vga;
  111.         hdc = GetDC(NULL);
  112.         if (GetDeviceCaps(hdc, VERTRES) <= 350)
  113.             dev->color_info = win_16ega_color;
  114.         else
  115.             dev->color_info = win_16vga_color;
  116.         ReleaseDC(NULL,hdc);
  117.         wdev->nColors = 16;
  118.     } 
  119.     else {   /* default is black_and_white */
  120.         wdev->nColors = 2;
  121.     }
  122.  
  123.     /* create palette for display */
  124.     if ((wdev->limgpalette = win_makepalette(wdev))
  125.         == (LPLOGPALETTE)NULL)
  126.         return win_nomemory();
  127.     wdev->himgpalette = CreatePalette(wdev->limgpalette);
  128.  
  129.     return 0;
  130. }
  131.  
  132. /* Make the output appear on the screen. */
  133. int
  134. win_sync_output(gx_device *dev)
  135. {
  136.     if (wdev->timer)
  137.         KillTimer(wdev->hwndimgchild, TIMER_ID);
  138.     wdev->timer = FALSE;
  139.     wdev->update = FALSE;
  140.     if (gsview) {
  141.     SendMessage(gsview_hwnd, WM_GSVIEW, SYNC_OUTPUT, (LPARAM)NULL);
  142.     }
  143.     else {
  144.     if ( !IsWindow(wdev->hwndimg) ) {  /* some clod closed the window */
  145.         win_makeimg(wdev);
  146.     }
  147.     if ( !IsIconic(wdev->hwndimg) ) {  /* redraw window */
  148.         InvalidateRect(wdev->hwndimg, NULL, 1);
  149.         UpdateWindow(wdev->hwndimg);
  150.     }
  151.     }
  152.     return(0);
  153. }
  154.  
  155. /* Make the window visible, and display the output. */
  156. int
  157. win_output_page(gx_device *dev, int copies, int flush)
  158. {
  159.     if (wdev->timer)
  160.         KillTimer(wdev->hwndimgchild, TIMER_ID);
  161.     wdev->timer = FALSE;
  162.     wdev->update = FALSE;
  163.  
  164.     if (gsview) {
  165.         SendMessage(gsview_hwnd, WM_GSVIEW, OUTPUT_PAGE, (LPARAM)NULL);
  166.         gsview_next = FALSE;
  167.         /* wait for NEXT_PAGE message */
  168.         while (!gsview_next)
  169.         gp_check_interrupts();
  170.         return(0);
  171.     }
  172.     else {
  173.         if (IsIconic(wdev->hwndimg))    /* useless as an Icon so fix it */
  174.         ShowWindow(wdev->hwndimg, SW_SHOWNORMAL);
  175.         BringWindowToTop(wdev->hwndimg);
  176.     }
  177.     return( win_sync_output(dev) );
  178. }
  179.  
  180. /* Close the win driver */
  181. int
  182. win_close(gx_device *dev)
  183. {
  184.     /* Free resources */
  185.     if (wdev->timer)
  186.         KillTimer(wdev->hwndimgchild, TIMER_ID);
  187.     wdev->timer = FALSE;
  188.     wdev->update = FALSE;
  189.  
  190.     DeleteObject(wdev->himgpalette);
  191.     gs_free((char *)(wdev->limgpalette), 1, sizeof(LOGPALETTE) + 
  192.         (1<<(wdev->color_info.depth)) * sizeof(PALETTEENTRY),
  193.         "win_close");
  194.     if (gsview)
  195.         DestroyWindow(wdev->hwndimgchild);
  196.     else
  197.         DestroyWindow(wdev->hwndimg);
  198.     gp_check_interrupts();    /* process WIN_DESTROY message */
  199.  
  200.     return(0);
  201. }
  202.  
  203. /* Map a r-g-b color to the colors available under Windows */
  204. gx_color_index
  205. win_map_rgb_color(gx_device *dev, gx_color_value r, gx_color_value g,
  206.   gx_color_value b)
  207. {
  208.     switch(dev->color_info.depth) {
  209.       case 8: {
  210.         int i;
  211.         LPLOGPALETTE lpal = wdev->limgpalette;
  212.         PALETTEENTRY *pep;
  213.         byte cr, cg, cb;
  214.  
  215.         /* map colors to 0->255 in 32 steps */
  216.         cr = win_color_value(r);
  217.         cg = win_color_value(g);
  218.         cb = win_color_value(b);
  219.  
  220.         /* search in palette */
  221.         for ( i = 0, pep = &lpal->palPalEntry[i];
  222.               i < wdev->nColors; i++, pep++
  223.             )
  224.         {    if ( !((cr ^ pep->peRed) & 0xf8) &&
  225.                  !((cg ^ pep->peGreen) & 0xf8) &&
  226.                  !((cb ^ pep->peBlue) & 0xf8)
  227.                )
  228.                 return((gx_color_index)i);    /* found it */
  229.         }
  230.         
  231.         /* next try adding it to palette */
  232.         if (i < 220) { /* allow 36 for windows and other apps */
  233.             LPLOGPALETTE lipal = wdev->limgpalette;
  234.             wdev->nColors = i+1;
  235.  
  236.             DeleteObject(wdev->himgpalette);
  237.              lipal->palPalEntry[i].peFlags = 0;
  238.             lipal->palPalEntry[i].peRed   =  cr;
  239.             lipal->palPalEntry[i].peGreen =  cg;
  240.             lipal->palPalEntry[i].peBlue  =  cb;
  241.             lipal->palNumEntries = wdev->nColors;
  242.             wdev->himgpalette = CreatePalette(lipal);
  243.  
  244.             return((gx_color_index)i);    /* return new palette index */
  245.         }
  246.  
  247.         return(gx_no_color_index);  /* not found - dither instead */
  248.         }
  249.       case 4:
  250.         if ((r == g) && (g == b) && (r >= gx_max_color_value / 3 * 2 - 1)
  251.            && (r < gx_max_color_value / 4 * 3))
  252.             return ((gx_color_index)8);    /* light gray */
  253.         return pc_4bit_map_rgb_color(dev, r, g, b);
  254.     }
  255.     return (gx_default_map_rgb_color(dev,r,g,b));
  256. }
  257.  
  258. /* Map a color code to r-g-b. */
  259. int
  260. win_map_color_rgb(gx_device *dev, gx_color_index color,
  261.   g